<template>
  <!--自定义表单设计组件-->
  <div class="designer">
    <div class="left">
      <div class="title">基础组件</div>
      <draggable class="items" v-model="dragList" :force-fallback="true" @start="onStart" @end="onEnd" :clone="cloneDefaultField" :group="{ name: 'list', pull: 'clone',put:false }" :sort="false">
        <div class="item" v-for="element in dragList" :key="element.componentName">
          <div class="unit">
            <i class="iconfont" :class="element.icon"></i>
            <span>{{ element.props.label }}</span>
          </div>
        </div>
      </draggable>
    </div>
    <div class="panl">
      <el-form readonly label-width="120px">
        <draggable v-model="widgetList" class="drag-content" @start="onStart2" @end="onEnd2" ghost-class="Vghost" drag-class="Vdrag" itemKey="id" :force-fallback="true" group="list" :fallback-class="true" :fallback-on-body="true">
          <div v-for="(element,index) in widgetList" class="widget" :key="index" @click="changeActive(element, index)">
            <div v-if="element.active" @click="deleteActive(index,element)" class="delete">
              <i class="el-icon-delete"></i> 删除
            </div>
            <el-alert class="itemx" :active="element.active" v-if="element.componentName === 'ShuoMingField'" :title="element.props.defaultValue" :closable="false" type="warning" />
            <el-form-item v-else :active="element.active" :required="element.props.required" class="item" :label="element.props.label">
              <el-input v-if="element.componentName === 'TextField'" v-model="element.props.defaultValue" :placeholder="element.props.placeholder" />
              <el-input v-if="element.componentName === 'TextAreaField'" type="textarea" v-model="element.props.defaultValue" :placeholder="element.props.placeholder" />
              <el-input-number v-if="element.componentName === 'NumberField'" v-model="element.props.defaultValue" :placeholder="element.props.placeholder" />
              <el-radio-group v-if="element.componentName === 'RadioField'" v-model="element.props.defaultValue">
                <el-radio v-for="(item,index) in element.props.options" :key="index" :label="item.value">{{item.label}}</el-radio>
              </el-radio-group>
              <el-checkbox-group v-if="element.componentName === 'CheckboxField'" v-model="element.props.defaultValue">
                <el-checkbox v-for="(item,index) in element.props.options" :key="index" :label="item.value">{{item.label}}</el-checkbox>
              </el-checkbox-group>
              <el-date-picker v-if="element.componentName === 'DatePickerField'" v-model="element.props.defaultValue" :placeholder="element.props.placeholder" />
              <el-date-picker v-if="element.componentName === 'DateRangePickerField'" v-model="element.props.defaultValue" type="daterange" range-separator="-" :start-placeholder="element.props.startPlaceholder" :end-placeholder="element.props.endPlaceholder" />
              <el-input v-if="element.componentName === 'TextCardField'" v-model="element.props.defaultValue" :placeholder="element.props.placeholder" />
              <el-input v-if="element.componentName === 'TextPhoneField'" v-model="element.props.defaultValue" :placeholder="element.props.placeholder" />
              <el-upload v-if="element.componentName === 'UploadFileField'" :file-list="element.props.defaultValue" action="https://myimage.mygctong.com/">
                <el-button type="primary" icon="el-icon-upload" plain>上传</el-button>
              </el-upload>
              <el-upload v-if="element.componentName === 'UploadImageField'" :file-list="element.props.defaultValue" action="https://myimage.mygctong.com/" list-type="picture-card">
                <i class="el-icon-plus"></i>
              </el-upload>
            </el-form-item>
          </div>
        </draggable>
      </el-form>
      <div class="drag">
        <img src="" alt="">
        点击或拖拽左侧控件至此处
      </div>
    </div>
    <div class="right" v-if="widgetList.length>0">
      <div class="title">
        <i class="iconfont" :class="widget().icon"></i>
        <span>{{widget().name}}</span>
      </div>
      <div class="list">
        <div class="item" v-if="showPropsName()">
          <div class="label">
            <span><i>*</i>唯一名称</span>
            <span>字段名称</span>
          </div>
          <el-tooltip v-if="IsNodeFlow(widget().props.name)" effect="dark" placement="bottom">
            <div slot="content">该组件已被设为审批条件，不可更改</div>
            <el-input maxlength="50" disabled v-model="widget().props.name" placeholder="" />
          </el-tooltip>
          <el-input maxlength="50" v-else v-model="widget().props.name" placeholder="" />
        </div>
        <div class="item" v-if="showPropsLabel()">
          <div class="label">
            <span>标题</span>
            <span>最多50字</span>
          </div>
          <el-input maxlength="50" v-model="widget().props.label" placeholder="" />
        </div>
        <div class="item" v-if="showPropsPlaceholder()">
          <div class="label">
            <span>提示文字</span>
            <span>最多50字</span>
          </div>
          <el-input maxlength="50" v-model="widget().props.placeholder" placeholder="" />
        </div>
        <div class="item" v-if="showPropsDefaultValue()">
          <div class="label">
            <span>默认值</span>
            <span></span>
          </div>
          <el-input maxlength="50" v-model="widget().props.defaultValue" placeholder="" />
        </div>
        <div class="item" v-if="showPropsOptionsValue()">
          <div class="label">
            <span>选项</span>
            <span>数据源</span>
          </div>
          <el-button type="text" @click="optionsDialog = true">编辑</el-button>
        </div>
        <div class="item" v-if="showPropsMultipleValue()">
          <div class="label">
            <span>上传数量</span>
            <span>最多上传</span>
          </div>
          <el-input maxlength="10" v-model="widget().props.multiple" placeholder="" />
        </div>
        <div class="item" v-if="showPropsRequired()">
          <div class="label">
            <span>必填</span>
            <span>{{widget().flowpath?'勾选后可作为流程条件':''}}</span>
          </div>
          <el-tooltip v-if="IsNodeFlow(widget().props.name)" effect="dark" placement="bottom">
            <div slot="content">该组件已被设为审批条件，不可更改</div>
            <el-switch active-color="#8BC349" disabled v-model="widget().props.required" />
          </el-tooltip>
          <el-switch v-else active-color="#8BC349" v-model="widget().props.required" />
        </div>
      </div>
    </div>
    <el-dialog title="编辑选项" :close-on-press-escape="false" :close-on-click-modal="false" :visible.sync="optionsDialog" width="500px">
      <div slot="title">
        编辑选项
        <el-button type="text" @click="addOption()">添加</el-button>
      </div>
      <el-table :data="widget().props.options">
        <el-table-column prop="label" label="键">
          <template slot-scope="scope">
            <el-input v-model="scope.row.label" placeholder="请输入键" />
          </template>
        </el-table-column>
        <el-table-column prop="value" label="值">
          <template slot-scope="scope">
            <el-input v-model="scope.row.value" placeholder="请输入值" />
          </template>
        </el-table-column>
        <el-table-column label="操作" width="80px">
          <template slot-scope="scope">
            <el-button type="text" @click="delOption(scope.$index)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-dialog>
  </div>
</template>

<script>
import draggable from 'vuedraggable'
import './iconfont/iconfont.css'

export default {
  name: 'approveDesigner',
  components: { draggable },
  props: ['node'],
  watch: {
    widgetList: {
      handler (newVal, oldVal) {
        this.$emit('changed', newVal)
      },
      deep: true,
      immediate: true
    }
  },
  data () {
    return {
      dragList: [
        {
          componentName: 'TextField',
          icon: 'icon-xianxing',
          active: false,
          name: '单行输入框',
          flowpath: true, // 是否可以作为创建流里的条件，当表单设计里的组件必填且可作为流程的条件时，则在流程面板设置条件中显示
          props: {
            label: '单行输入框',
            placeholder: '请输入',
            id: '',
            required: true,
            defaultValue: '',
            name: ''
          }
        },
        {
          componentName: 'TextAreaField',
          icon: 'icon-dh',
          active: false,
          name: '多行输入框',
          flowpath: true,
          props: {
            label: '多行输入框',
            placeholder: '请输入',
            id: '',
            required: true,
            defaultValue: '',
            name: ''
          }
        },
        {
          componentName: 'NumberField',
          icon: 'icon-sz',
          active: false,
          name: '数字输入框',
          flowpath: true,
          props: {
            label: '数字输入框',
            placeholder: '请输入',
            id: '',
            required: true,
            defaultValue: '',
            name: ''
          }
        },
        {
          componentName: 'RadioField',
          icon: 'icon-danxuankuang',
          active: false,
          name: '单选框',
          flowpath: true,
          props: {
            label: '单选框',
            placeholder: '请选择',
            id: '',
            required: true,
            defaultValue: '',
            name: '',
            options: [
              {
                label: '默认项',
                value: 0
              }
            ]
          }
        },
        {
          componentName: 'CheckboxField',
          icon: 'icon-dxk',
          active: false,
          name: '多选框',
          flowpath: true,
          props: {
            label: '多选框',
            placeholder: '请选择',
            id: '',
            required: true,
            defaultValue: '',
            name: '',
            options: [
              {
                label: '默认项',
                value: 0
              }
            ]
          }
        },
        {
          componentName: 'DatePickerField',
          icon: 'icon-riqi',
          active: false,
          name: '日期',
          flowpath: true,
          props: {
            label: '日期',
            placeholder: '请选择',
            id: '',
            required: true,
            defaultValue: '',
            name: ''
          }
        },
        {
          componentName: 'DateRangePickerField',
          icon: 'icon-rqqj',
          active: false,
          name: '日期区间',
          flowpath: true,
          props: {
            label: '日期区间',
            placeholder: '请选择',
            id: '',
            name: '',
            required: true,
            defaultValue: '',
            startPlaceholder: '开始日期',
            endPlaceholder: '结束日期'
          }
        },
        {
          componentName: 'ShuoMingField',
          icon: 'icon-shuoming',
          active: false,
          name: '说明文字',
          flowpath: false,
          props: {
            label: '说明文字',
            placeholder: '请输入',
            id: '',
            required: true,
            defaultValue: '请输入说明文字',
            name: ''
          }
        },
        {
          componentName: 'TextCardField',
          icon: 'icon-sfz',
          active: false,
          name: '身份证',
          flowpath: true,
          props: {
            label: '身份证',
            placeholder: '请输入',
            id: '',
            required: true,
            defaultValue: '',
            name: ''
          }
        },
        {
          componentName: 'TextPhoneField',
          icon: 'icon-shouji',
          active: false,
          name: '电话',
          flowpath: true,
          props: {
            label: '电话',
            placeholder: '请输入',
            id: '',
            required: true,
            defaultValue: '',
            name: ''
          }
        },
        {
          componentName: 'UploadFileField',
          icon: 'icon-fujian',
          active: false,
          name: '附件',
          flowpath: false,
          props: {
            label: '附件',
            placeholder: '',
            id: '',
            required: true,
            defaultValue: [],
            multiple: 1,
            name: ''
          }
        },
        {
          componentName: 'UploadImageField',
          icon: 'icon-tp',
          active: false,
          name: '图片',
          flowpath: false,
          props: {
            label: '图片',
            placeholder: '',
            id: '',
            required: true,
            defaultValue: [],
            multiple: 1,
            name: ''
          }
        }
      ],
      widgetList: [],
      IndexActive: 0,
      optionsDialog: false,
      isDrag: false
    }
  },
  methods: {
    addOption () {
      this.widget().props.options.push({
        label: '默认项',
        value: 0
      })
    },
    delOption (i) {
      this.widget().props.options.splice(i, 1)
    },
    widget () {
      return this.widgetList[this.IndexActive]
        ? this.widgetList[this.IndexActive]
        : { props: {} }
    },
    changeActive (item, index) {
      this.widgetList.forEach((model) => {
        model.active = false
      })
      item.active = true
      this.IndexActive = index
    },
    // 判定组件是否被设为流程条件
    IsNodeFlow (name) {
      if (JSON.stringify(this.node).indexOf(name) > -1) {
        return true
      }
      return false
    },
    deleteActive (index, item) {
      // 删除之前，判定组件是否被设为流程条件，如果被设置为流程条件，禁止删除
      if (this.IsNodeFlow(item.props.name)) {
        this.$message.error('该组件已被设为审批条件，不可删除')
        return
      }
      const _cacheWidget = [...this.widgetList]
      _cacheWidget.splice(index, 1)
      if (index > _cacheWidget.length - 1) {
        this.IndexActive = index - 1
      }
      this.widgetList = [..._cacheWidget]
    },
    getKeyRandom () {
      let text = ''
      const possible =
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
      for (let i = 0; i < 10; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)) }
      return text
    },
    cloneDefaultField (e) {
      e.props.name = e.componentName + '_' + this.getKeyRandom()
      e.props.id = this.getKeyRandom()
      return JSON.parse(JSON.stringify(e))
    },
    onStart () {
      this.isDrag = true
    },
    onEnd () {
      this.isDrag = false
      if (this.widgetList.length === 1) {
        this.widgetList[0].active = true
      }
    },
    onStart2 () {
      this.isDrag = true
    },
    onEnd2 () {
      this.isDrag = false
    },
    showPropsName () {
      const name = this.widget().componentName
      if (
        name === 'TextField' ||
        name === 'TextAreaField' ||
        name === 'NumberField' ||
        name === 'RadioField' ||
        name === 'CheckboxField' ||
        name === 'DatePickerField' ||
        name === 'DateRangePickerField' ||
        name === 'TextCardField' ||
        name === 'TextPhoneField' ||
        name === 'UploadFileField' ||
        name === 'UploadImageField'
      ) {
        return true
      }
      return false
    },
    showPropsLabel () {
      const name = this.widget().componentName
      if (
        name === 'TextField' ||
        name === 'TextAreaField' ||
        name === 'NumberField' ||
        name === 'RadioField' ||
        name === 'CheckboxField' ||
        name === 'DatePickerField' ||
        name === 'DateRangePickerField' ||
        name === 'TextCardField' ||
        name === 'TextPhoneField' ||
        name === 'UploadFileField' ||
        name === 'UploadImageField'
      ) {
        return true
      }
      return false
    },
    showPropsPlaceholder () {
      const name = this.widget().componentName
      if (
        name === 'TextField' ||
        name === 'TextAreaField' ||
        name === 'NumberField' ||
        name === 'RadioField' ||
        name === 'CheckboxField' ||
        name === 'DatePickerField' ||
        name === 'DateRangePickerField' ||
        name === 'TextCardField' ||
        name === 'TextPhoneField'
      ) {
        return true
      }
      return false
    },
    showPropsDefaultValue () {
      const name = this.widget().componentName
      if (
        name === 'TextField' ||
        name === 'TextAreaField' ||
        name === 'NumberField' ||
        name === 'RadioField' ||
        name === 'CheckboxField' ||
        name === 'ShuoMingField' ||
        name === 'DatePickerField' ||
        name === 'DateRangePickerField' ||
        name === 'TextCardField' ||
        name === 'TextPhoneField'
        // name === "UploadFileField" ||
        // name === "UploadImageField"
      ) {
        return true
      }
      return false
    },
    showPropsOptionsValue () {
      const name = this.widget().componentName
      if (name === 'RadioField' || name === 'CheckboxField') {
        return true
      }
      return false
    },
    showPropsMultipleValue () {
      const name = this.widget().componentName
      if (name === 'UploadFileField' || name === 'UploadImageField') {
        return true
      }
      return false
    },
    showPropsRequired () {
      const name = this.widget().componentName
      if (
        name === 'TextField' ||
        name === 'TextAreaField' ||
        name === 'NumberField' ||
        name === 'RadioField' ||
        name === 'CheckboxField' ||
        name === 'DatePickerField' ||
        name === 'DateRangePickerField' ||
        name === 'TextCardField' ||
        name === 'TextPhoneField' ||
        name === 'UploadFileField' ||
        name === 'UploadImageField'
      ) {
        return true
      }
      return false
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep .el-input__inner {
  background: #fff !important;
}
::v-deep .el-checkbox {
  padding-right: inherit;
  border-right: inherit;
  margin: inherit;
  margin-right: 30px;
}
.Vghost {
  height: 2px;
  border-left: 2px solid #8bc349 !important;
  background: #8bc349 !important;
  padding: 0 !important;
  margin-bottom: 10px !important;
  *,
  .el-form-item__label {
    display: none !important;
  }
}
.Vghost:hover {
  border-left: 2px solid #8bc349 !important;
}
.Vdrag {
  .delete {
    display: none;
  }
}
.designer {
  width: 100%;
  height: calc(100vh - 54px);
  background: #fff;
  .left {
    width: 255px;
    background: #f9f9f9;
    border-right: 1px solid #ecedef;
    position: relative;
    padding: 0 12px;
    padding-top: 12px;
    height: calc(100% - 12px);
    display: inline-block;
    vertical-align: top;
    .title {
      display: flex;
      align-items: center;
      padding-bottom: 8px;
      font-weight: 500;
      padding-left: 2px;
      margin-right: 6px;
      font-family: PingFangSC-Medium;
      font-size: 12px;
      color: #171a1d;
    }
    .items {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: space-between;
      .item {
        position: relative;
        width: 120px;
        height: 40px;
        display: flex;
        align-items: center;
        margin-bottom: 12px;
        border: 1px solid transparent;
        border-radius: 8px;
        cursor: grab;
        background-color: #fff;
        .unit {
          display: flex;
          align-items: center;
          width: 100%;
          height: 100%;
          i {
            margin: 0 8px;
          }
          span {
            display: flex;
            align-items: center;
            line-height: 16px;
            font-size: 12px;
            color: #111f2c;
          }
        }
      }
      .item:hover {
        border-color: #8bc349;
        box-shadow: 0 4px 8px 0 rgba(17, 31, 44, 0.08);
      }
    }
  }
  .panl {
    position: relative;
    width: calc(100% - 580px - 48px);
    height: calc(100vh - 54px - 124px);
    overflow-y: auto;
    display: inline-block;
    padding: 24px 24px 100px;
    vertical-align: top;
    .drag {
      display: flex;
      align-items: center;
      justify-content: center;
      padding-top: 4px;
      font-size: 14px;
      color: rgba(23, 26, 29, 0.4);
      img {
        height: 13px;
        margin-right: 6px;
      }
    }
    .item {
      position: relative;
      margin-bottom: 10px;
      border-left: 3px solid #fff;
      transition: 0.3s all ease;
      background: #fff;
      padding: 10px;
    }
    .widget {
      position: relative;
      .delete {
        position: absolute;
        z-index: 1001;
        right: 0;
        background: #8bc349;
        padding: 2px 5px;
        cursor: pointer;
        font-size: 14px;
        color: #fff;
      }
    }
    .itemx {
      border-left: 3px solid #fff;
      margin-bottom: 10px;
    }
    .item::before {
      content: "";
      z-index: 99;
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      background: transparent;
    }
    .item:hover,
    .itemx:hover {
      z-index: 999;
      border-left: 3px solid #bfc1c2;
      box-shadow: 0 1px 10px 0 rgba(226, 226, 226, 0.5);
      cursor: grab;
    }
    .item[active="true"],
    .itemx[active="true"] {
      z-index: 999;
      border-left: 3px solid #8bc349 !important;
      box-shadow: 0 1px 10px 0 rgba(226, 226, 226, 0.5);
      border-radius: 0;
      // padding-right: 50px;
      .btn {
        display: inline;
      }
    }
  }
  .right {
    width: 299px;
    background: #fff;
    border-left: 1px solid #ecedef;
    display: inline-block;
    vertical-align: top;
    height: 100%;
    .title {
      display: flex;
      align-items: center;
      height: 48px;
      padding: 0 12px;
      border-bottom: 1px solid #f0f0f0;
      i {
        margin-right: 4px;
      }
      span {
        font-size: 14px;
        color: #191f25;
        line-height: 22px;
      }
    }
    .list {
      padding: 12px;
      .item {
        margin-bottom: 24px;
        .label {
          display: flex;
          align-items: center;
          flex-wrap: wrap;
          margin-bottom: 6px;
          i {
            color: red;
            margin-right: 2px;
          }
          span {
            margin-right: 8px;
            font-size: 14px;
            display: inline-flex;
            align-items: center;
          }
          span:last-child {
            font-size: 12px;
            color: rgba(25, 31, 37, 0.4);
            line-height: 18px;
          }
        }
      }
    }
  }
}
.drag-content {
  min-height: 350px;
}
</style>
